package com.lagou.boot;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.ContextConfig;
import org.apache.catalina.startup.Tomcat;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName SpringAppliction
 * @Description 提供一个run方法，用来启动tomcat
 * @Author playboy
 * @Date 2021/5/15 2:12 下午
 * @Version 1.0
 **/
public class SpringApplication {

	/**
	 * 服务器端口
	 */
	private int port = 8080;

	/**
	 * 服务器地址
	 */
	private InetAddress address;

	/**
	 * 线程名称设置是标记id
	 */
	private static final AtomicInteger containerCounter = new AtomicInteger(-1);

	/**
	 * 服务协议
	 */
	public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol";


	/**
	 * 启动tomcat
	 */
	public void run() throws LifecycleException {
		Tomcat tomcat = new Tomcat();
		//设置基础路径
		tomcat.setBaseDir(createTempDir("tomcat").getAbsolutePath());

		//创建Connector
		Connector connector = new Connector(DEFAULT_PROTOCOL);

		tomcat.getService().addConnector(connector);

		//设置connector
		connector.setPort(getPort());
		connector.setURIEncoding("UTF-8");
		connector.setProperty("bindOnInit", "false");

		tomcat.setConnector(connector);
		tomcat.getHost().setAutoDeploy(false);
		tomcat.getEngine().setBackgroundProcessorDelay(10);

		//创建context，并进行设置
		StandardContext context = new StandardContext();
		context.setName("");
		context.setDisplayName("application");
		context.setPath("");
		context.setDocBase(createTempDir("tomcat-docbase").getAbsolutePath());
		context.addLifecycleListener(new Tomcat.FixContextListener());
		//这一行很关键，只有增加这一行，容器才会去解析META-INF/services/javax.servlet.ServletContainerInitialize
		context.addLifecycleListener(new ContextConfig());

		WebappLoader loader = new WebappLoader();
		loader.setDelegate(true);
		context.setLoader(loader);

		//设置session时间
		context.setSessionTimeout(30);

		tomcat.getHost().addChild(context);


		containerCounter.incrementAndGet();

		tomcat.start();


		Thread awaitThread = new Thread("container-" + (containerCounter.get())) {

			@Override
			public void run() {
				tomcat.getServer().await();
			}

		};
		awaitThread.setContextClassLoader(getClass().getClassLoader());
		awaitThread.setDaemon(false);
		awaitThread.start();

	}


	protected final File createTempDir(String prefix) {
		try {
			File tempDir = File.createTempFile(prefix + ".", "." + getPort());
			tempDir.delete();
			tempDir.mkdir();
			tempDir.deleteOnExit();
			return tempDir;
		} catch (IOException ex) {
			throw new RuntimeException("设置");
		}
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public InetAddress getAddress() {
		return address;
	}

	public void setAddress(InetAddress address) {
		this.address = address;
	}
}
